function myFn () {
  console.log(this.name)
  console.log(arguments)
}
const obj = {
  name: 'zs'
}
// myFn.call(obj, 'aa', 'bb')

/*
new Object 构造函数为给定的参数创建一个包装类对象（object wrapper），具体有以下情况：
如果给定值是 null 或 undefined，将会创建并返回一个空对象
如果传进去的是一个基本类型的值，则会构造其包装类型的对象
如果传进去的是引用类型的值，仍然会返回这个值，经他们复制的变量保有和源对象相同的引用地址
当以非构造函数形式被调用时，Object 的行为等同于 new Object()。
*/

Function.prototype.mycall = function (context) {
  console.log(this)
  // 短路运算符，如果有context，则就是context，否则就等于window
  let args = [...arguments].slice(1)
  context = context || window
  context.fn = this

  let res = context.fn(...args)
  delete context.fn
  return res
}
myFn.mycall(obj, 'aaa', 'bbb')
/*
call的思路:
普通函数fn本质上也是一个对象,我们将mycall方法挂载到Function.prototype上
此时调用fn,发现它没有mycall方法,之后就会向原型链上去查找
找到了mycall方法,此时我们打印this,这个this指向的是fn,也就是谁调用它就指向谁
此时我们需要更改它的指向
将需要指向的obj传递进来
此时在obj下挂载一个函数,fn2
也就是obj.fn2指向当前的fn函数
就可以通过我们之前的this,
obj.fn2=this
此时
也就是相当于
obj={
  name:'zs'
  fn2:function(){
    return fn(){console.log(this.name)}
  }
}
我们在调用fn中的this.name,就会向它的上层中去寻找name,也就是达到了改变this指向的问题

下一步是考虑接受参数
将arguments进行slice切割,之后传递到fn中即可
*/
